use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// 知识图谱中的概念节点
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct Concept {
    pub name: String,
    pub description: String,
    pub confidence: u32, // 0-100，知识的确信度
    pub learned_from: Vec<String>, // 从哪些对话中学到
}

/// 加权关系 - 包含权重和因果信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WeightedRelation {
    pub relation_type: RelationType,
    pub weight: f64,           // 0.0-1.0，关系强度
    pub causal_sign: i8,       // -1(负因果), 0(非因果), 1(正因果)
    pub usage_count: usize,    // 使用次数
    pub last_used: Option<std::time::SystemTime>,
}

/// 关系类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RelationType {
    IsA(String, String),           // A是B的一种
    PartOf(String, String),        // A是B的一部分
    Causes(String, String),        // A导致B
    Requires(String, String),      // A需要B
    Similar(String, String),       // A类似于B
    Opposite(String, String),      // A与B相反
    HasProperty(String, String),   // A具有属性B
    CanDo(String, String),         // A能做B
}

/// 兼容旧的Relation类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Relation {
    IsA(String, String),
    PartOf(String, String),
    Causes(String, String),
    Requires(String, String),
    Similar(String, String),
    Opposite(String, String),
    HasProperty(String, String),
    CanDo(String, String),
}

impl Relation {
    fn to_string(&self) -> String {
        match self {
            Relation::IsA(a, b) => format!("{} 是 {}", a, b),
            Relation::PartOf(a, b) => format!("{} 是{}的一部分", a, b),
            Relation::Causes(a, b) => format!("{} 导致 {}", a, b),
            Relation::Requires(a, b) => format!("{} 需要 {}", a, b),
            Relation::Similar(a, b) => format!("{} 类似于 {}", a, b),
            Relation::Opposite(a, b) => format!("{} 与{}相反", a, b),
            Relation::HasProperty(a, b) => format!("{} 具有 {}", a, b),
            Relation::CanDo(a, b) => format!("{} 能做 {}", a, b),
        }
    }
}

/// 动态知识图谱 - 升级版，支持加权边和自动管理
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KnowledgeGraph {
    pub concepts: HashMap<String, Concept>,  // 改为pub让推理链能访问
    relations: Vec<Relation>,
    weighted_relations: Vec<WeightedRelation>,  // 新增：加权关系
    interaction_count: usize,
    auto_prune: bool,  // 是否自动删除低权重边
    prune_threshold: f64,  // 删除阈值
}

impl KnowledgeGraph {
    pub fn new() -> Self {
        KnowledgeGraph {
            concepts: HashMap::new(),
            relations: Vec::new(),
            weighted_relations: Vec::new(),
            interaction_count: 0,
            auto_prune: true,
            prune_threshold: 0.1,  // 权重低于0.1会被删除
        }
    }

    /// 启用/禁用自动修剪
    pub fn set_auto_prune(&mut self, enabled: bool, threshold: f64) {
        self.auto_prune = enabled;
        self.prune_threshold = threshold;
    }

    /// 添加或更新概念
    pub fn add_concept(&mut self, name: &str, description: &str, source: &str) {
        let name = name.to_lowercase();
        
        if let Some(concept) = self.concepts.get_mut(&name) {
            // 更新现有概念
            concept.description = description.to_string();
            concept.confidence = (concept.confidence + 10).min(100);
            concept.learned_from.push(source.to_string());
        } else {
            // 创建新概念
            self.concepts.insert(
                name.clone(),
                Concept {
                    name: name.clone(),
                    description: description.to_string(),
                    confidence: 60,
                    learned_from: vec![source.to_string()],
                },
            );
        }
    }

    /// 添加关系（兼容旧API）
    pub fn add_relation(&mut self, relation: Relation) {
        // 检查是否已存在
        let relation_str = relation.to_string();
        let exists = self.relations.iter().any(|r| r.to_string() == relation_str);
        
        if !exists {
            // 转换为加权关系
            let causal_sign = match &relation {
                Relation::Causes(_, _) => 1,  // 正因果
                Relation::Opposite(_, _) => -1,  // 可能是负相关
                _ => 0,
            };
            
            let weighted = WeightedRelation {
                relation_type: self.relation_to_type(&relation),
                weight: 0.8,  // 初始权重
                causal_sign,
                usage_count: 1,
                last_used: Some(std::time::SystemTime::now()),
            };
            
            self.relations.push(relation);
            self.weighted_relations.push(weighted);
        } else {
            // 如果存在，增强权重
            self.strengthen_relation(&relation_str);
        }
    }

    /// 关系转类型
    fn relation_to_type(&self, relation: &Relation) -> RelationType {
        match relation {
            Relation::IsA(a, b) => RelationType::IsA(a.clone(), b.clone()),
            Relation::PartOf(a, b) => RelationType::PartOf(a.clone(), b.clone()),
            Relation::Causes(a, b) => RelationType::Causes(a.clone(), b.clone()),
            Relation::Requires(a, b) => RelationType::Requires(a.clone(), b.clone()),
            Relation::Similar(a, b) => RelationType::Similar(a.clone(), b.clone()),
            Relation::Opposite(a, b) => RelationType::Opposite(a.clone(), b.clone()),
            Relation::HasProperty(a, b) => RelationType::HasProperty(a.clone(), b.clone()),
            Relation::CanDo(a, b) => RelationType::CanDo(a.clone(), b.clone()),
        }
    }

    /// 增强关系权重
    fn strengthen_relation(&mut self, relation_str: &str) {
        for (i, rel) in self.relations.iter().enumerate() {
            if rel.to_string() == relation_str {
                if let Some(weighted) = self.weighted_relations.get_mut(i) {
                    weighted.weight = (weighted.weight + 0.1).min(1.0);
                    weighted.usage_count += 1;
                    weighted.last_used = Some(std::time::SystemTime::now());
                }
                break;
            }
        }
    }

    /// 弱化关系权重
    pub fn weaken_relation(&mut self, relation_str: &str, amount: f64) {
        for (i, rel) in self.relations.iter().enumerate() {
            if rel.to_string() == relation_str {
                if let Some(weighted) = self.weighted_relations.get_mut(i) {
                    weighted.weight = (weighted.weight - amount).max(0.0);
                    
                    // 如果权重过低且启用自动修剪，删除该边
                    if weighted.weight < self.prune_threshold && self.auto_prune {
                        println!("  🗑️  自动删除低权重边: {}", relation_str);
                        self.relations.remove(i);
                        self.weighted_relations.remove(i);
                    }
                }
                break;
            }
        }
    }

    /// 主动修剪低权重边
    pub fn prune_weak_relations(&mut self) -> usize {
        let initial_count = self.relations.len();
        
        let mut indices_to_remove = Vec::new();
        for (i, weighted) in self.weighted_relations.iter().enumerate() {
            if weighted.weight < self.prune_threshold {
                indices_to_remove.push(i);
            }
        }
        
        // 从后往前删除
        indices_to_remove.sort_by(|a, b| b.cmp(a));
        for i in indices_to_remove {
            self.relations.remove(i);
            self.weighted_relations.remove(i);
        }
        
        initial_count - self.relations.len()
    }

    /// 获取高权重关系
    pub fn get_strong_relations(&self, threshold: f64) -> Vec<(String, f64)> {
        self.relations
            .iter()
            .zip(self.weighted_relations.iter())
            .filter(|(_, w)| w.weight >= threshold)
            .map(|(r, w)| (r.to_string(), w.weight))
            .collect()
    }

    /// 获取因果链
    pub fn get_causal_chain(&self, start: &str) -> Vec<String> {
        let mut chain = Vec::new();
        let mut current = start.to_string();
        let mut visited = std::collections::HashSet::new();
        
        while !visited.contains(&current) {
            visited.insert(current.clone());
            
            // 查找因果关系
            let mut found = false;
            for (i, rel) in self.relations.iter().enumerate() {
                if let Relation::Causes(a, b) = rel {
                    if a == &current {
                        if let Some(weighted) = self.weighted_relations.get(i) {
                            if weighted.causal_sign == 1 && weighted.weight > 0.5 {
                                chain.push(format!("{} → {} (权重: {:.2})", a, b, weighted.weight));
                                current = b.clone();
                                found = true;
                                break;
                            }
                        }
                    }
                }
            }
            
            if !found {
                break;
            }
        }
        
        chain
    }

    /// 检查概念是否存在
    pub fn has_concept(&self, name: &str) -> bool {
        self.concepts.contains_key(&name.to_lowercase())
    }

    /// 获取概念
    pub fn get_concept(&self, name: &str) -> Option<&Concept> {
        self.concepts.get(&name.to_lowercase())
    }

    /// 获取所有关系（用于知识转移）
    pub fn get_all_relations(&self) -> Vec<Relation> {
        self.relations.clone()
    }

    /// 查找相关概念
    pub fn find_related(&self, concept: &str) -> Vec<String> {
        let concept = concept.to_lowercase();
        let mut related = Vec::new();

        for relation in &self.relations {
            match relation {
                Relation::IsA(a, b) | Relation::PartOf(a, b) | Relation::Causes(a, b)
                | Relation::Requires(a, b) | Relation::Similar(a, b) | Relation::Opposite(a, b)
                | Relation::HasProperty(a, b) | Relation::CanDo(a, b) => {
                    if a.to_lowercase() == concept {
                        related.push(b.clone());
                    } else if b.to_lowercase() == concept {
                        related.push(a.clone());
                    }
                }
            }
        }

        related
    }

    /// 推理：基于已知知识推导新知识
    pub fn infer_new_knowledge(&mut self) -> Vec<String> {
        let mut inferences = Vec::new();

        // 传递性推理：如果 A是B，B是C，则 A是C
        let isa_relations: Vec<(String, String)> = self
            .relations
            .iter()
            .filter_map(|r| {
                if let Relation::IsA(a, b) = r {
                    Some((a.clone(), b.clone()))
                } else {
                    None
                }
            })
            .collect();

        for (a, b) in &isa_relations {
            for (c, d) in &isa_relations {
                if b == c {
                    let new_relation = Relation::IsA(a.clone(), d.clone());
                    let new_str = format!("通过传递推理：{} 是 {}", a, d);
                    
                    if !self.relations.iter().any(|r| {
                        if let Relation::IsA(x, y) = r {
                            x == a && y == d
                        } else {
                            false
                        }
                    }) {
                        self.add_relation(new_relation);
                        inferences.push(new_str);
                    }
                }
            }
        }

        // 因果推理：如果 A导致B，B导致C，则 A可能导致C
        let cause_relations: Vec<(String, String)> = self
            .relations
            .iter()
            .filter_map(|r| {
                if let Relation::Causes(a, b) = r {
                    Some((a.clone(), b.clone()))
                } else {
                    None
                }
            })
            .collect();

        for (a, b) in &cause_relations {
            for (c, d) in &cause_relations {
                if b == c && a != d {
                    let new_str = format!("推理：{} 可能间接导致 {}", a, d);
                    inferences.push(new_str);
                }
            }
        }

        inferences
    }

    /// 记录交互
    pub fn record_interaction(&mut self) {
        self.interaction_count += 1;
    }

    /// 获取统计信息
    pub fn get_stats(&self) -> String {
        format!(
            "知识图谱统计:\n  概念数: {}\n  关系数: {}\n  交互次数: {}",
            self.concepts.len(),
            self.relations.len(),
            self.interaction_count
        )
    }

    /// 导出知识
    pub fn export_knowledge(&self) -> Vec<String> {
        let mut knowledge = Vec::new();

        knowledge.push("===== 已学习的概念 =====".to_string());
        for (_, concept) in &self.concepts {
            knowledge.push(format!(
                "• {} (确信度:{}%): {}",
                concept.name, concept.confidence, concept.description
            ));
        }

        knowledge.push("\n===== 已知的关系 =====".to_string());
        for relation in &self.relations {
            knowledge.push(format!("• {}", relation.to_string()));
        }

        knowledge
    }
}

impl Default for KnowledgeGraph {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_knowledge_graph() {
        let mut kg = KnowledgeGraph::new();
        kg.add_concept("ai", "人工智能", "test");
        kg.add_concept("机器学习", "AI的子领域", "test");
        
        kg.add_relation(Relation::IsA("机器学习".to_string(), "ai".to_string()));
        
        assert!(kg.has_concept("ai"));
        assert_eq!(kg.concepts.len(), 2);
        assert_eq!(kg.relations.len(), 1);
    }

    #[test]
    fn test_inference() {
        let mut kg = KnowledgeGraph::new();
        kg.add_relation(Relation::IsA("深度学习".to_string(), "机器学习".to_string()));
        kg.add_relation(Relation::IsA("机器学习".to_string(), "AI".to_string()));
        
        let inferences = kg.infer_new_knowledge();
        assert!(!inferences.is_empty());
    }
}

